package po

import (
	"golang.org/x/image/math/f64"
	"math"
)

type Bullet struct {
	BulletType     BulletType
	BulletMoveType BulletMoveType
	Dir            f64.Vec2
	Position       f64.Vec2
	TargetPos      f64.Vec2
	BulletSpeed    float64
	Damage         int
	Life           int
	Scale          float64
}

func (b *Bullet) BulletMove() {
	b.Life--
	switch b.BulletMoveType {
	case Linear:
		b.Position[0] += b.BulletSpeed * b.Dir[0]
		b.Position[1] -= b.BulletSpeed * b.Dir[1]
	case Homing:
		if b.TargetPos[0] == 0 {
			b.Position[0] += b.BulletSpeed * b.Dir[0]
			b.Position[1] -= b.BulletSpeed * b.Dir[1]
			return
		}
		if b.Life < 170 {
			target := b.TargetPos
			current := f64.Vec2{b.Dir[0], b.Dir[1]}
			toTarget := f64.Vec2{
				target[0] - b.Position[0],
				-(target[1] - b.Position[1]),
			}
			maxAnglePerFrame := 0.1
			b.Dir = TurnToward(current, toTarget, maxAnglePerFrame)
		}
		b.Position[0] += b.BulletSpeed * b.Dir[0]
		b.Position[1] -= b.BulletSpeed * b.Dir[1]
	}

}

// 返回两个向量之间的夹角
func angleBetween(a, b f64.Vec2) float64 {
	dot := a[0]*b[0] + a[1]*b[1]
	det := a[0]*b[1] - a[1]*b[0]
	return math.Atan2(det, dot) // atan2(y, x)
}

// 将向量按角度旋转
func rotateVec2(v f64.Vec2, angle float64) f64.Vec2 {
	sin, cos := math.Sinh(angle), math.Cosh(angle)
	return f64.Vec2{
		v[0]*cos - v[1]*sin,
		v[0]*sin + v[1]*cos,
	}
}

// TurnToward 将当前方向逐渐转向目标方向（限制最大旋转角）
func TurnToward(current, target f64.Vec2, maxDelta float64) f64.Vec2 {
	current = normalize(current)
	target = normalize(target)
	angle := angleBetween(current, target)

	if math.Abs(angle) <= maxDelta {
		return target // 直接对准目标
	}

	// 限制旋转角度
	if angle > 0 {
		angle = maxDelta
	} else {
		angle = -maxDelta
	}
	res := normalize(rotateVec2(current, angle))
	return f64.Vec2{res[0], res[1]}
}

func normalize(v f64.Vec2) f64.Vec2 {
	l := math.Hypot(v[0], v[1])
	if l == 0 {
		return f64.Vec2{0, 0}
	}
	return f64.Vec2{v[0] / l, v[1] / l}
}
